/*
 * @(#)TriggerWorkflowAction.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.rules.action;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringBufferInputStream;
import java.sql.Connection;
import java.util.List;

import org.mandarax.eca.ActionException;

import com.dcivision.dms.bean.EmailMessageToRule;
import com.dcivision.form.bean.FormSubmission;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.DataSourceFactory;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.mail.bean.EmailAttachmentImpl;
import com.dcivision.mail.bean.EmailMessageImpl;
import com.dcivision.rules.RuleOperationConstant;
import com.dcivision.user.bean.UserRecord;
import com.dcivision.user.dao.UserRecordDAObject;
import com.dcivision.workflow.bean.WorkflowProgress;
import com.dcivision.workflow.bean.WorkflowRecord;
import com.dcivision.workflow.core.SystemWorkflowConstant;
import com.dcivision.workflow.core.WorkflowProgressManager;
import com.dcivision.workflow.dao.WorkflowRecordDAObject;
import com.dcivision.workflow.web.MaintWorkflowRecordForm;


/**
 * <p>Class Name:  TriggerWorkflowAction </p>
 * <p>Description: This class will trigger a workflow.</p>
 * 
 * @author         Tony Chen
 * @company        DCIVision Limited
 * @creation date  29/07/2005
 * @version        $Revision: 1.8 $
 */
public class TriggerWorkflowAction extends AbstractRuleAction {	
  
  private   String STORAGE_ROOT = SystemParameterFactory.getSystemParameter(SystemParameterConstant.WORKFLOW_ATTACHMENT_PHYSICAL_PATH);
  /**
   * Perform an action.
   * @param param the action parameters
   */
  public void perform(Object[] param) throws ActionException {
  	String workflowRecordID = null;
    String userRecordID = null;
    String[] tempArr = TextUtility.splitString((String)this.getTarget(), RuleOperationConstant.SPLIT_STRING);
    
    workflowRecordID = tempArr[0];
    userRecordID = tempArr[1];
  	log.debug("================= Trigger Workflow Action ====================" + this.getTarget() );
    
    Connection dbConn = null;
    WorkflowProgress workflowProgress = null;
    
    try{
      dbConn = DataSourceFactory.getConnection();
      
      SessionContainer sessionContainer = this.getSessionContainer();

      //get the message bean
      EmailMessageToRule emailMessage = (EmailMessageToRule)param[0];
      EmailMessageImpl emailMessageImpl =  EmailMessageImpl.newInstance();
      emailMessageImpl.setEmailMessageData(emailMessage);
      
      if ( !Utility.isEmpty(emailMessage.getMessgeUserID()) ) {
        sessionContainer.getUserRecord().setID(emailMessage.getMessgeUserID());
      }
      
      log.debug("sessionContainer.getSessionID():" + sessionContainer.getSessionID());
      STORAGE_ROOT += "/" + sessionContainer.getSessionID();
      
      //get the submitter, and set it to SessionContainer
      UserRecordDAObject userDAO = new UserRecordDAObject(sessionContainer, dbConn);      
      UserRecord userRecord = (UserRecord) userDAO.getObjectByID(new Integer(userRecordID));
      sessionContainer.setUserRecord(userRecord);
      
      WorkflowRecordDAObject recordDAO = new WorkflowRecordDAObject(sessionContainer, dbConn);
      WorkflowProgressManager progressManager = new WorkflowProgressManager(sessionContainer, dbConn);

      WorkflowRecord workflowRecord =(WorkflowRecord)recordDAO.getObjectByID(new Integer(workflowRecordID));
      
      //check workflowRecord Effective Period
      if ( Utility.isEmpty(workflowRecord.getEndDate()) || 
          workflowRecord.getEndDate().after(Utility.getCurrentTimestamp()) ) {
        
      	MaintWorkflowRecordForm recordForm = new MaintWorkflowRecordForm();
      	recordForm.setFileNames( this.getUploadAttachmentName(emailMessageImpl) );
      	recordForm.setFormData(workflowRecord);
      	
      	if( new Integer(SystemWorkflowConstant.FMB_SUBMISSION_BY_FORM).equals(workflowRecord.getWorkflowCategoryID()) ){
      		FormSubmission formSubmision = progressManager.recordFormSubmission(new Integer(workflowRecordID) ); 
      		recordForm.setWorkflowObject( formSubmision );
      		recordForm.setTrackID(formSubmision.getTrackID().toString());
      	}
      	
      	log.debug("Trigger a workflow record begin, ID is " + workflowRecordID);
      	workflowProgress = (WorkflowProgress) progressManager.startWorkflowTrack(recordForm);
      	log.debug("Trigger a workflow end. Track ID is " + workflowProgress.getTrackID());
      	dbConn.commit();
      } else {
        log.debug("The workflow expired. ");  
      }
    } catch (ApplicationException appEx) {
    	log.debug(" Application Exception :", appEx);
      log.error(appEx);
    } catch (Exception e) {
    	log.debug(" Trigger a workflow occur Fatal Error.");
      log.error(e);
    } finally {
      try { dbConn.close(); } catch (Exception ignore) {} finally { dbConn = null; }
    }

  }

  /**
   * get the upload attachment name(s)
   * @param emailMessage
   * @throws ApplicationException
   */
  private String getUploadAttachmentName(EmailMessageImpl emailMessage) throws ApplicationException {
    InputStream inputStream = null;
    
    String subject = emailMessage.getSubject();
    Object content = emailMessage.getContent();
    
    log.debug("subject: " + subject);
    log.debug("content: " + content.toString());
    
    List attachmentList = emailMessage.getAttachments();
    String attachmentName = "";
    int count = 0;
    //get the email message file
    String convertedName = String.valueOf(System.currentTimeMillis());
    String originalName = subject + ".txt";
    log.debug("convertedName: " + convertedName);

    File convertedFile = new File(STORAGE_ROOT + "/" + convertedName);
    if (!convertedFile.exists()){
      //convertedName = convertedName + String.valueOf(System.currentTimeMillis());
      convertedFile = new File(STORAGE_ROOT + "/" + convertedName);
      attachmentName += originalName + ":" + convertedName;
      count++;
    }            
     
    StringBufferInputStream sInputStream = new StringBufferInputStream(content.toString());
    this.newFile(sInputStream, convertedFile);
    
    
    //get the attachement file
    for (int i = 0; i < attachmentList.size(); i++) {
      EmailAttachmentImpl attachment = (EmailAttachmentImpl) attachmentList.get(i); 
      log.debug("attachment name: " + attachment.getAttachFileName() );
     
      convertedName = String.valueOf(System.currentTimeMillis() + (i + 1) * 10 );
      log.debug("convertedName: " + convertedName);
      convertedFile = new File(STORAGE_ROOT + "/" + convertedName);
      log.debug("convertedFile:" + convertedFile);      
  
      this.newFile(this.getAttachmentFileInputSteam(attachment), convertedFile);		
      if (!Utility.isEmpty(attachmentName)){
        attachmentName += "|";
      }
      attachmentName += attachment.getAttachFileName() + ":" + convertedName;
      count++;
    }
    attachmentName = count + "|" + attachmentName;
    log.debug("==================attachmentName:" + attachmentName);
    return attachmentName;
  }
  
  /**
   * get attachment file InputSteam
   * @param emailAttachment
   * @return DataInputStream
   * @throws Exception
   */
  private InputStream getAttachmentFileInputSteam(EmailAttachmentImpl emailAttachment) throws ApplicationException {
    InputStream inputStream = null;      
    String cachePath = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_CACHEFOLDER_PATH);
    String trueFilePath = cachePath + emailAttachment.getCatchFileName();
    log.debug("cachePath: " + cachePath);
    log.debug("trueFilePath: " + trueFilePath);
    
    File file = new File(trueFilePath);
    if (file.exists()) {
      try {
				inputStream = new BufferedInputStream(new FileInputStream(trueFilePath));
			} catch (FileNotFoundException e) {
        log.debug("File Not Found Exception.");
        throw new ApplicationException("File not found exception");
			}
    }
    return inputStream;
  }
  
  /**
   * new a file 
   * @param inputStream
   * @param file
   * @throws ApplicationException
   */
  private void newFile(InputStream inputStream, File file) throws ApplicationException {
    int length = -1;
    int bufferSize = 8192;
    byte[] buffer = new byte[bufferSize];
    FileOutputStream fos = null;
    
    try {
      fos = new FileOutputStream(file);    
      while ((length = inputStream.read(buffer, 0, bufferSize)) != -1) {      
        fos.write(buffer, 0, length);
      }
      fos.flush();      
      inputStream.close();      
      fos.close();
    } catch (FileNotFoundException e) {      
      log.debug("File Not Found Exception.");
      throw new ApplicationException("File not found exception");
    } catch (IOException e1) {     
      log.debug("IO Exception");
      throw new ApplicationException("IO Exception");
    }
  }
}
